package View.UserFilterDialog;

import Model.LinearFilter;
import View.LinearFilterTable.LinearFilterTable;
import View.LinearFilterTable.LinearFilterTableCellEditor;
import View.MainFrame;
import View.MyListCellRenderer;

import javax.swing.*;
import javax.swing.text.NumberFormatter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.text.NumberFormat;

/**
 * Created by IntelliJ IDEA.
 * User: Andrew
 * Date: 08.03.12
 * Time: 18:31
 * To change this template use File | Settings | File Templates.
 */
public class UserFilterDialog extends JDialog implements ActionListener {
    private MainFrame parentFrame;

    private JComboBox<LinearFilter> jcbFilters;
    private JSeparator separator1 = new JSeparator(SwingConstants.HORIZONTAL);
    private JSeparator separator2 = new JSeparator(SwingConstants.HORIZONTAL);
    private JButton jbtnUse = new JButton("Use");
    private JButton jbtnExit = new JButton("Exit");
    private JButton jbtnRename = new JButton("Rename");
    private JButton jbtnNew = new JButton("New");
    private JButton jbtnSave = new JButton("Save");
    private JButton jbtnDelete = new JButton("Delete");
    private JPanel jpSizes = new JPanel(new BorderLayout());
    private ButtonGroup btngrSizes = new ButtonGroup();
    private JRadioButton jrbtnThree = new JRadioButton("3x3");
    private JRadioButton jrbtnFive = new JRadioButton("5x5");
    private JFormattedTextField jtfDiv = new JFormattedTextField();
    private LinearFilter currentFilter;
    private LinearFilter sourceFilter;
    private LinearFilterTable myTable = new LinearFilterTable(this);
    private UserFilterDialogListener myListener;
    //private EnterNameDialog enterNameDialog;
    
    static final private String RENAME = "RENAME";
    static final private String COMMAND_NEW = "COMMAND_NEW";
    {
        NumberFormat format = NumberFormat.getInstance();
        new NumberFormatter(format).install(jtfDiv);
    }

    public LinearFilter getCurrentFilter() {
        return currentFilter;
    }

    public void setListener(UserFilterDialogListener myListener) {
        this.myListener = myListener;
    }

    public void actionPerformed(ActionEvent ae) {
        if (ae.getActionCommand().equals("Filter")) {
            ((LinearFilterTableCellEditor)myTable.getDefaultEditor(Float.class)).stop();
            sourceFilter = (LinearFilter)jcbFilters.getSelectedItem();
            if (sourceFilter == null)
                return;
            currentFilter = new LinearFilter(sourceFilter);
            myTable.getTableModel().setRowData(currentFilter);
            myTable.getTableModel().fireTableDataChanged();
            if (currentFilter.getSize() == 3)
                jrbtnThree.setSelected(true);
            else
                jrbtnFive.setSelected(true);
            jtfDiv.setText(String.valueOf(currentFilter.getDiv()));
        }
        if (ae.getActionCommand().equals("Use")) {
            myListener.eventOccured(new UserFilterDialogEvent(currentFilter, UserFilterDialogEvent.USE_FILTER)) ;
        }
        if (ae.getActionCommand().equals("Save")) {
            //myListener.eventOccured(new UserFilterDialogEvent((LinearFilter)jcbFilters.getSelectedItem(), UserFilterDialogEvent.SAVE_FILTER)) ;
            if (currentFilter == null) {
                return;
            }
            sourceFilter.setName(currentFilter.getName());
            sourceFilter.setData(currentFilter.getData());
            sourceFilter.setSize(currentFilter.getSize());
            sourceFilter.setDiv(currentFilter.getDiv());
        }
        if (ae.getActionCommand().equals("Exit")) {
            this.setVisible(false);
        }
        if (ae.getActionCommand().equals("Delete")) {
            parentFrame.getImageModel().getFilterLibrary().remove(sourceFilter);
            jcbFilters.removeItem(sourceFilter);
            if (parentFrame.getImageModel().getFilterLibrary().size() > 0) {
                jcbFilters.setSelectedIndex(0);
            } else {
                jcbFilters.setSelectedIndex(-1);
                myTable.setEnabled(false);
                jbtnDelete.setEnabled(false);
                jbtnSave.setEnabled(false);
                jbtnRename.setEnabled(false);
                jbtnUse.setEnabled(false);
                jrbtnFive.setEnabled(false);
                jrbtnThree.setEnabled(false);
                jtfDiv.setEnabled(false);
            }              
        }
        if (ae.getActionCommand().equals("Three")) {
            ((LinearFilterTableCellEditor)myTable.getDefaultEditor(Float.class)).stop();
            currentFilter.setSize(3);
            float[] a = currentFilter.getData();
            float[] data = new float[]{a[6], a[7], a[8], a[11], a[12], a[13], a[16], a[17], a[18]};
            currentFilter.setData(data);
            myTable.getTableModel().fireTableDataChanged();
        }
        if (ae.getActionCommand().equals("Five")) {
            ((LinearFilterTableCellEditor)myTable.getDefaultEditor(Float.class)).stop();
            currentFilter.setSize(5);
            float[] a = currentFilter.getData();
            float[] data = new float[]{0, 0, 0, 0, 0, 0, a[0], a[1], a[2], 0, 0, a[3], a[4], a[5], 0, 0, a[6], a[7], a[8], 0, 0, 0, 0, 0, 0};
            currentFilter.setData(data);
            myTable.getTableModel().fireTableDataChanged();
        }
        /*if (ae.getActionCommand().equals("Div")) {
            float x = currentFilter.getDiv();
            try {
                x = Float.parseFloat(jtfDiv.getText());
            } catch (Exception ex) {}
            finally {
                currentFilter.setDiv(x);
            }
        }*/
         if (ae.getActionCommand().equals(RENAME)) {
            //enterNameDialog = new EnterNameDialog(currentFilter.getName(), this);
            //enterNameDialog.setVisible(true);

            String newName = (String)JOptionPane.showInputDialog(this, "Enter new name:", "Rename", JOptionPane.PLAIN_MESSAGE, null, null, sourceFilter.getName());
            if (newName != null) {
                if (!newName.equals(sourceFilter.getName())) {
                    LinearFilter filter = parentFrame.getImageModel().getFilterByName(newName);
                    if (filter != null)
                        JOptionPane.showMessageDialog(this, "Filter with this name has already exist!", "Error!", JOptionPane.ERROR_MESSAGE);
                     else {
                        sourceFilter.setName(newName);
                        jcbFilters.updateUI();
                    }
                }
            }
        }

        if (ae.getActionCommand().equals(COMMAND_NEW)) {
            //enterNameDialog = new EnterNameDialog(currentFilter.getName(), this);
            //enterNameDialog.setVisible(true);
            String newName = "NewFilter";
            LinearFilter filter = parentFrame.getImageModel().getFilterByName(newName);
            while (filter != null) {
                newName = newName + "1";
                filter = parentFrame.getImageModel().getFilterByName(newName);
            }
            newName = (String)JOptionPane.showInputDialog(this, "Enter name:", "New filter", JOptionPane.PLAIN_MESSAGE, null, null, newName);
            if (newName != null) {
                filter = parentFrame.getImageModel().getFilterByName(newName);
                if (filter != null)
                    JOptionPane.showMessageDialog(this, "Filter with this name already exists!", "Error!", JOptionPane.ERROR_MESSAGE);
                else {
                    LinearFilter newFilter = new LinearFilter(newName, 3, null, 1.0f);
                    parentFrame.getImageModel().getFilterLibrary().add(newFilter);
                    jcbFilters.addItem(newFilter);
                    jcbFilters.setSelectedItem(newFilter);
                    myTable.setEnabled(true);
                    jbtnDelete.setEnabled(true);
                    jbtnSave.setEnabled(true);
                    jbtnRename.setEnabled(true);
                    jbtnUse.setEnabled(true);
                    jrbtnFive.setEnabled(true);
                    jrbtnThree.setEnabled(true);
                    jtfDiv.setEnabled(true);

               }
            }
        }
    }

    public UserFilterDialog(MainFrame frame) {
        super(frame, true);
        parentFrame = frame;
        setTitle("Linear Filters");
        setLocationRelativeTo(parentFrame);
        setSize(600, 200);
        setResizable(false);

        LinearFilter a[] = new LinearFilter[]{};

        jcbFilters = new JComboBox<LinearFilter>(parentFrame.getImageModel().getFilterLibrary().toArray(a));
        jcbFilters.setRenderer(new MyListCellRenderer());
        jcbFilters.setPreferredSize(new Dimension(180, 20));
        jcbFilters.setActionCommand("Filter");

        
        if (parentFrame.getImageModel().getFilterLibrary().size() > 0) {
            jcbFilters.setSelectedIndex(0);
            sourceFilter = (LinearFilter)jcbFilters.getSelectedItem();
            currentFilter = new LinearFilter(sourceFilter);
        }
        else {
            jcbFilters.setSelectedIndex(-1);
            myTable.setEnabled(false);
            jbtnDelete.setEnabled(false);
            jbtnSave.setEnabled(false);
            jbtnRename.setEnabled(false);
            jbtnUse.setEnabled(false);
            jrbtnFive.setEnabled(false);
            jrbtnThree.setEnabled(false);
            sourceFilter = null;
            currentFilter = new LinearFilter("", 3, null, 1.0f);
        }
        myTable.getTableModel().setRowData(currentFilter);


        jcbFilters.addActionListener(this);

        GridBagLayout gbag = new GridBagLayout();
        setLayout(gbag);
        separator1.setSize(500, 5);
        separator2.setSize(500, 5);
        jrbtnThree.setActionCommand("Three");
        jrbtnThree.addActionListener(this);
        jrbtnFive.setActionCommand("Five");
        jrbtnFive.addActionListener(this);
        jpSizes.add(jrbtnThree, BorderLayout.NORTH);
        jpSizes.add(jrbtnFive, BorderLayout.SOUTH);
        jpSizes.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Size"), BorderFactory.createEmptyBorder(0, 5, 0, 5)));
        btngrSizes.add(jrbtnThree);
        btngrSizes.add(jrbtnFive);

        if (currentFilter.getSize() == 3)
            jrbtnThree.setSelected(true);
        else
            jrbtnFive.setSelected(true);

        jtfDiv.setText(String.valueOf(currentFilter.getDiv()));

        gbag.setConstraints(jbtnRename, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 10, 0, 5), 0, 0));
        gbag.setConstraints(jcbFilters, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 10), 0, 0));
        gbag.setConstraints(jbtnNew, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
        gbag.setConstraints(jbtnSave, new GridBagConstraints(3, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 5), 0, 0));
        gbag.setConstraints(jbtnDelete, new GridBagConstraints(4, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));

        gbag.setConstraints(separator1, new GridBagConstraints(0, 1, 5, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 0), 0, 0));

        gbag.setConstraints(myTable, new GridBagConstraints(0, 2, 2, 3, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 10, 0, 10), 0, 0));
        gbag.setConstraints(jpSizes, new GridBagConstraints(2, 2, 1, 2, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
        JLabel divLabel = new JLabel("Div ");
        gbag.setConstraints(divLabel, new GridBagConstraints(2, 4, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_END, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
        gbag.setConstraints(jtfDiv, new GridBagConstraints(3, 4, 2, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
 
        gbag.setConstraints(separator2, new GridBagConstraints(0, 5, 5, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 0), 0, 0));

        gbag.setConstraints(jbtnUse, new GridBagConstraints(0, 6, 2, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 10, 0, 10), 0, 0));
        gbag.setConstraints(jbtnExit, new GridBagConstraints(3, 6, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
 
        jtfDiv.setFocusLostBehavior(JFormattedTextField.COMMIT_OR_REVERT);
        jtfDiv.addFocusListener(new FocusAdapter() {
            @Override
            public void focusLost(FocusEvent e) {
                float x = currentFilter.getDiv();


                Float newx = 0.f;

                try {
                    String text = jtfDiv.getText();
                    newx = Float.parseFloat(text);
                } catch (Exception ex) {
                    newx = x;
                   jtfDiv.setText(newx.toString());
                } finally {
                    if (newx > 0){
                        currentFilter.setDiv(newx);
                    }else if (newx < 0){
                        newx = -newx;
                        currentFilter.setDiv(newx);
                        jtfDiv.setText(newx.toString());
                    }else{
                        newx = x;
                        jtfDiv.setText(newx.toString());
                    }


                }
            }
        });

        jbtnUse.setActionCommand("Use");
        jbtnUse.addActionListener(this);
        jbtnExit.setActionCommand("Exit");
        jbtnExit.addActionListener(this);
        jbtnSave.setActionCommand("Save");
        jbtnSave.addActionListener(this);
        jbtnDelete.setActionCommand("Delete");
        jbtnDelete.addActionListener(this);
        jtfDiv.setActionCommand("Div");
        jtfDiv.addActionListener(this);
        getContentPane().add(jcbFilters);
        getContentPane().add(separator1);
        getContentPane().add(separator2);
        getContentPane().add(jbtnUse);
        getContentPane().add(jbtnExit);
        getContentPane().add(jbtnNew);
        getContentPane().add(jbtnSave);
        getContentPane().add(jbtnDelete);
        getContentPane().add(jpSizes);
        getContentPane().add(divLabel);
        getContentPane().add(jtfDiv);
        //getContentPane().add(jrbtnThree);
        //getContentPane().add(jrbtnFive);
        getContentPane().add(myTable);
        getContentPane().add(jbtnRename);
        jbtnRename.setActionCommand(RENAME);
        jbtnRename.addActionListener(this);
        jbtnNew.setActionCommand(COMMAND_NEW);
        jbtnNew.addActionListener(this);
    }
}
